#pragma  once
#include "stdafx.h"
#include "connector.h"
#include "units.h"
#include "scene.h"
#include "title.h"
#include "parameters_model.h"
#include "common.h"
#include "flow_tracker.h"
#include "sensor.h"
//class ConnectorClass;
class QGraphicsSceneMouseEvent;
class SceneView;
class Common;
class autConPoint;
class Sensor;
class Title;
class ParametersModel;
class Delegate;
class FlowTracker;
class Indicator;
class autConnector;

class automaticItem : public QGraphicsObject
{
	Q_OBJECT

public:
	static const enum type_t {SENSOR, FLOWTRACKER, CONTROLLER};
	automaticItem(SceneView* _scene, const int &_type, const QString &_name, const QPointF &_pos, const QString &_parent);
	automaticItem(SceneView* _scene, const int &_type);
	~automaticItem();
	QRectF boundingRect() const;
	void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
	
	QString getStringType();
	vector<autConPoint*> getListOfAutConPoint(){ return list_of_connection_point; }
	bool isAllowedManyConnectors(){ return allowedManyConnectors; }
	QRectF getSize(){ return size; }
	type_t getType(){ return type; }
	void setTitle(Title* _title);
	Title* getTitle(){ return title; }
	QString getTitleText();
	void setSize(const QRectF &_size);
	//ParametersModel* getModel();
	autConPoint* autConPointAt(int index);
	//QVariant getParameter(const QString &name, const QString &script = "COMMON");
	void setPosition(const QPointF &_pos);
	ParametersModel* getModel(){ return model; }
	bool isVisibleOnScene();
	void setVisibleOnScene( const bool &_visible );
	Sensor* getSensor(){ return sensor; }
	double getNumParameter(const QString &name, const QString &script = "COMMON");
	QString getStringParameter(const QString &name, const QString &script = "COMMON");
	void adjust(const QPointF &pos);
	QPointF getIndicatorPos();
	Indicator* getIndicator();
	void setIndicator(Indicator* _indicator);
	QString getParentName(){ return parent; }
	QString getName();
	bool isSensor(){ return type == SENSOR; }
	bool isFlowTracker(){ return type == FLOWTRACKER; }
	void setFlowTrackerWidth(const double &width, const bool &visible_new_conPoint = false);
	double getFlowTrackerWidth(){ return size.width(); };
	hash_map<string, QVector<double>> getData(){ return Data; }
	void addDataLayer(const QString &parameter, const double &value);
private:
	hash_map<string, QVector<double>> Data;
	SceneView* scene;
	ParametersModel* model;
	Title* title;
	Indicator* indicator;
	Delegate* delegate;
	//QString name;
	const type_t type;
	bool resize;
	QString parent;
	vector<autConPoint*> list_of_connection_point;
	QRectF size;
	bool allowedManyConnectors;
	Sensor *sensor;
	FlowTracker *flow_tracker;
	void setSize();
	void drawFlowTracker(QPainter *painter);
	void drawSensor(QPainter *painter);
	//void init_model();
	void updateautConPointPosition();
	void addAutConPoint();
	void resizeFlowTracker(const double &current_x_pos, const bool &visible_new_conPoint);
	void updateSensorTooltip();
	void init_model();
protected:
	void mousePressEvent(QGraphicsSceneMouseEvent *event);
	void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
	void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
	void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
	void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
	void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
	QVariant itemChange(GraphicsItemChange change, const QVariant &value);
private slots:
	void getNewParameterValue(const QString &_name, const QVariant &_value);
	void update_parameters();
	void removeItem();
	void func(const QString &_parameter_name);
	void removeScriptParameter(const QString &script_name);
	void addScriptParameter(const QString &script_name);
	void createTrend(const QString &_parameter);
	void clear_data();
	void update_indicator(const int & timestamp_index);
public slots:
	void showIndicator();
	void showIndicatorLine();
signals:
	void setNewParameterValue(const QString &_name, const QVariant &_value);
	void updateName(const QString &);
};

class autConPoint : public QGraphicsObject
{
	Q_OBJECT

public:
	static const enum direction_t {ALL, UP, DOWN, LEFT, RIGHT};
	autConPoint(SceneView* _scene, automaticItem* _source, const QPointF &_position_relative_source, const QString &tooltip, const direction_t &_direction = ALL);
	~autConPoint();
	direction_t direction;
	QRectF boundingRect() const;
	void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
	void adjust();
	void setAccepted(bool _accepted){ accepted = _accepted; }
	bool isAccepted(){ return accepted; }
	bool isAllowedAddConnector(){ return (!connectors.size() || source->isAllowedManyConnectors()); }
	void addConnector(autConnector* _connector){ connectors.push_back(_connector); }
	void removeConnector(autConnector* _connector){ connectors.erase(find(connectors.begin(), connectors.end(), _connector)); }
	autConnector* getConnector(int index){ if (!connectors.size()) return NULL; return connectors[index]; }
	void setPositionRelativeSource(QPointF _position_relative_source){ position_relative_source = _position_relative_source; adjust(); }
	QPointF getPositionRelativeSource(){ return position_relative_source; }
	QString getParentName(){ return source->getTitleText(); }
	automaticItem::type_t getParentType(){ return source->getType(); }
	int getIndexInParentsList();
	automaticItem* getParent(){ return source; }
	bool isChild(autConnector* _connector);
	bool isAnyDirection(){ return direction == ALL;	 }
	automaticItem* getOtherItem();
	QPointF getDirectionPoint();
private:
	vector<autConnector*> connectors;
	SceneView* scene;
	automaticItem* source;
	QPointF position_relative_source;
	bool accepted;
protected:
	void mousePressEvent(QGraphicsSceneMouseEvent *event);
signals:
	void posChanged(const QPointF&);
};
